﻿using System.Collections.Generic;
using Microsoft.Practices.Unity;
using Web7.Container.Models;
using Web7.Core.Security;
using Web7.Core.Security.Users;
using Web7.Domain;
using Web7.Utilities;

namespace Web7.Container.Services
{
    public class MemberShipService : IMemberShip
    {
        [Dependency]
        public IUserRolesPartService UserRolesPartService { get; set; }

        [Dependency]
        public IRoleService RoleService { get; set; }

        [Dependency]
        public IUserService UserService { get; set; }

        public IEnumerable<Role> GetRoleMemberOfUser(IUser user)
        {
            List<Role> roles = new List<Role>();

            var u = user as Entity;
            var userRoles = UserRolesPartService.Fetch(r => r.UserId == u.Id);

            foreach (var item in userRoles)
            {
                roles.Add(RoleService.Get(role => role.Id == item.RoleId));
            }

            return (roles as IEnumerable<Role>);
        }

        public IEnumerable<IUser> GetUserMemberOfRole(Role role)
        {
            List<User> users = new List<User>();

            var roleUsers = UserRolesPartService.Fetch(u => u.RoleId == role.Id);

            foreach (var item in roleUsers)
            {
                users.Add(UserService.Get(user => user.Id == item.UserId));
            }

            return (users as IEnumerable<IUser>);
        }

        public IUser ValidateUser(string userNameOrEmail, string password)
        {
            var lowerName = userNameOrEmail == null ? "" : userNameOrEmail.ToLowerInvariant();

            var user = UserService.Get(u => u.UserName == lowerName);

            if (user == null)
                user = UserService.Get(u => u.Email == lowerName);

            if (user == null || !ValidatePassword(user, password))
                return new UserAnonymous();

            //if (user.EmailStatus != UserStatus.PendingApproval) //todo:邮件及用户状态验证，暂时先不启用
            //    return new UserAnonymous();

            //if (user.Status != UserStatus.PendingApproval)
            //    return new UserAnonymous();

            return user;
        }

        private bool ValidatePassword(User user, string password)
        {
            bool result = false;

            switch (user.PasswordFormat)
            {
                case SymmetricEncryptType.RC2:
                    result = user.Password.Equals(EncryptManager.Encrypt(SymmetricEncryptType.RC2, password));
                    break;
                case SymmetricEncryptType.DES:
                    result = user.Password.Equals(EncryptManager.Encrypt(SymmetricEncryptType.DES, password));
                    break;
                case SymmetricEncryptType.TripleDES:
                    result = user.Password.Equals(EncryptManager.Encrypt(SymmetricEncryptType.TripleDES, password));
                    break;
                case SymmetricEncryptType.Rijndael:
                    result = user.Password.Equals(EncryptManager.Encrypt(SymmetricEncryptType.Rijndael, password));
                    break;
            }

            return result;
        }
    }
}
